﻿/***  File Header  ************************************************************/
/**
* @file P4thLex.cpp
*
* P4th字句解析モジュール
* @author shozo fukuda
* @date   作成 Tue Feb 14 19:23:08 2006
* @date   修正 $Date: 06/04/13 14:26 $
* System  Generic <br>
*
*******************************************************************************/

/*******************************************************************************
* IMPORTS:
*******************************************************************************/
#include <ctype.h>
#include "P4th.h" /* 呼出用 */

/*******************************************************************************
* CONSTANT:
*******************************************************************************/

/*******************************************************************************
* TYPE:
*******************************************************************************/

/*******************************************************************************
* MACRO:
*******************************************************************************/

/*******************************************************************************
* GLOBAL VARIABLE:
*******************************************************************************/

/***  Module Header  ******************************************************}}}*/
/**
* 文字読み取り
* @par 解説
*   テキストバッファから一文字読み取ります。読み取りがテキスト終端に達したなら
*   ば、以降の呼び出しでは終端文字'\0'を繰り返し返します。
*
* @return 読み取った文字
**/
/**************************************************************************{{{*/
char P4th::Read()
{
  char c = *mCP;
  if (c != EOS) {
    mCP++;
  }
  return c;
}

/***  Module Header  ******************************************************}}}*/
/**
* 文字書き戻し
* @par 解説
*   文字cをテキストバッファに書き戻します。
**/
/**************************************************************************{{{*/
void P4th::PutBack(
char c)
{
  if (mCP > mTextBuff) {
    *--mCP = c;

  } else {
    /*+TODO:shoz:06/02/13:バッファオーバーフローの異常処理を記述すること */
  }
}

/***  Module Header  ******************************************************}}}*/
/**
* ワード文字列の読み取り
* @par 解説
*   入力テキストから空白文字を読み飛ばした後、1ワード分の文字列を読み取りバッファ
*   cstrtにセットします。
*
* @return   読み取ったワードの文字長
**/
/**************************************************************************{{{*/
int P4th::ReadWord(
UCHAR* cstr)          ///< (w) ワード文字列バッファ
{
  int c;
  int n = 0;

  /* 空白文字の読み飛ばし */
  do {
    c = Read();
  } while (c != EOS && c != EOL && !isgraph(c));

  /* ワード文字列を読み込み */
  while (isgraph(c)) {
    if (n < WORD_LENGTH) {
      n++;
      cstr[n] = c;
    }
    c = Read();
  }
  if (c == EOL) {
    PutBack(c);
  }
  cstr[0] = n;

  /* 英小文字 -> 英大文字変換 */
  if (iCapital) {
    ToUpper(cstr);
  }
  
  return n;
}

/***  Module Header  ******************************************************}}}*/
/**
* 字句解析
* @par 解説
*   入力テキストの先頭から区切り文字dlmtまでの文字列を取り出し、テンポラリmName
*   に格納します。
**/
/**************************************************************************{{{*/
void P4th::Parse(
int dlmt)           ///< (r) 区切り文字
{
  char c;
  int  n = 0;
  
  c = Read();
  while (!c && c != EOL && c != dlmt) {
    if (n < MAX_COUNTED_STRING) {
      n++;
      mName[n] = c;
    }
    c = Read();
  }
  if (c == EOL && dlmt != EOL) {
    PutBack(c);
  }
  
  mName[0] = n;
}

/***  Module Header  ******************************************************}}}*/
/**
* 字句解析
* @par 解説
*   入力テキストから区切り文字dlmtで区切られる文字列を取り出し、テンポラリmName
*   に格納します。入力テキストの先頭にある区切り文字は全て読み飛ばされます。
**/
/**************************************************************************{{{*/
void P4th::ParseWord(
int dlmt)           ///< (r) 区切り文字
{
  char c;
  int  n = 0;

  if (isspace(dlmt)) {
    do {
      c = Read();
    } while (!c && c != EOL && !isgraph(c));
    
    while (isgraph(c)) {
      if (n < MAX_COUNTED_STRING) {
        n++;
        mName[n] = c;
      }
      c = Read();
    }
    if (c == EOL) {
      PutBack(c);
    }
    
  } else {
    do {
      c = Read();
    } while (!c && c != EOL && c == dlmt);
    
    while (!c && c != EOL && c != dlmt) {
      if (n < MAX_COUNTED_STRING) {
        n++;
        mName[n] = c;
      }
      c = Read();
    }
    if (c == EOL && dlmt != EOL) {
      PutBack(c);
    }
  }
  
  mName[0] = n;
}

/***  Module Header  ******************************************************}}}*/
/**
* カウント付き文字列の大文字変換
* @par 解説
*   カウント付き文字列cstr内の英小文字を全て英大文字に置き変えます。
**/
/**************************************************************************{{{*/
void P4th::ToUpper(
UCHAR* cstr)
{
  long len = *cstr++;

  while (len-- > 0) {
    *cstr = toupper(*cstr);
    cstr++;
  }
}

/***  Module Header  ******************************************************}}}*/
/**
* 
* カウント付き文字列とC-文字列の一致判定
* @par 解説
*   カウント付き文字列cstrの比較開始位置iから始まる部分文字列が C-文字列strと一
*   致するかどうかを判定します。部分文字列が一致した場合、カウント付き文字列内の
*   一致部分の次の文字位置を関数値として返します。
*
* @retval 0 不一致
* @retval i カウント付き文字列内の一致部分文字列の次の文字位置
**/
/**************************************************************************{{{*/
long P4th::MatchCStrStr(
UCHAR* cstr,        ///< (r)  カウント付き文字列
char*  str,         ///< (r)  C-文字列
long   i)           ///< (rw) カウント付き文字列の比較開始位置 {1 <= i <= *cstr}
{
  long len = cstr[0];

/*PRECONDITION*/
  if (len == 0      // cstrが空文字列
  ||  *str == '\0'  // strが空文字列
  ||  i < 1         // 比較開始位置が文字列範囲外
  ||  i > len) {    // 比較開始位置が文字列範囲外
    return 0;
  }
/* */

  while (*str) {
    if (i > len || cstr[i] != *str) {
      return 0;
    }
    i++;
    str++;
  }
  return i;
}

/***  Module Header  ******************************************************}}}*/
/**
* 
* C-文字列とカウント付き文字列の比較
* @par 解説
*   C-文字列strとカウント付き文字列cstrが等しいかどうかを比較します。
*
* @retval true  ２つの文字列が等しい
* @retval false ２つの文字列が等しくない
**/
/**************************************************************************{{{*/
bool P4th::EqCStrStr(
UCHAR* cstr,        ///< (r)  カウント付き文字列
char*  str)         ///< (r)  C-文字列
{
  long i = MatchCStrStr(cstr, str);
  
  return (i == (*cstr + 1));
}

/* end of P4thLex.cpp */

